package com.course.chapter1;

import java.util.ArrayList;
import java.util.List;

public class Ticket extends Thread {

    private static int index =1;
    private static final int MAX =10000;
    private static List<Integer> list =new ArrayList<>(1000);
    @Override
    public void run() {
        getTicket4();
    }

    /**
     * 每个线程都能获取到对应的锁 (锁对应的是当前对象)
     * 多线程下不安全
     */
    public synchronized void getTicket1(){
        while (index<=MAX){
            list.add(index);
            System.out.println(Thread.currentThread().getName()+"当前号码："+(index++));
        }
    }

    /**
     * 只有一个线程能够获取到锁 (锁对应的是当前类)
     */
    public synchronized static void getTicket2(){
        while (index<=MAX){
            list.add(index);
            System.out.println(Thread.currentThread().getName()+"当前号码："+(index++));
        }
    }
    /**
     * 每个线程都能获取到对应的锁 (锁对应的是当前对象)
     * 多线程下不安全
     */
    public void getTicket3(){
        synchronized(this){
            while (index<=MAX){
                list.add(index);
                System.out.println(Thread.currentThread().getName()+"当前号码："+(index++));
            }
        }
    }

    public void getTicket4(){
        synchronized(Ticket.class){
            while (index<=MAX){
                list.add(index);
                System.out.println(Thread.currentThread().getName()+"当前号码："+(index++));
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Ticket ticket1 = new Ticket();
        Ticket ticket2 = new Ticket();
        Ticket ticket3 = new Ticket();
        Ticket ticket4 = new Ticket();
        /**
         * start() 可以启动一个新线程，run()不能
         * start()不能被重复调用，run()可以
         * start()中的run代码可以不执行完就继续执行下面的代码，即进行了线程切换。直接调用run方法必须等待其代码全部执行完才能继续执行下面的代码。
         * start() 实现了多线程，run()没有实现多线程。
         *
         */
        ticket1.start();
        ticket2.start();
        ticket3.start();
        ticket4.start();
        ticket1.join();
        ticket2.join();
        ticket3.join();
        ticket4.join();
//        List<Integer> collect = list.stream().sorted().collect(Collectors.toList());
        System.out.println(list);
    }
}
